package p.sunmes.les.actor;

import java.util.HashMap;
import java.util.Map;

import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.Group;
import com.badlogic.gdx.scenes.scene2d.Touchable;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.utils.Align;

public class RegionLabel extends Group {

	private Map<Character, TextureRegion> dict;
	private String text = "";
	private int charWidth = 10;
	private int charHeight = 10;
	private int maxWidth = Integer.MAX_VALUE;
	private boolean isAutoSize;

	private void initialized(TextureRegion tex, String chars, int charWidth,
			int charHeight) {
		this.charWidth = charWidth;
		this.charHeight = charHeight;

		dict = new HashMap<Character, TextureRegion>();
		int xCount = tex.getRegionWidth() / charWidth;
		int lines = tex.getRegionHeight() / charHeight;
		if (xCount < 1 || lines < 1 || charWidth <= 0 || charHeight <= 0) {
			throw new IllegalArgumentException(
					"charWidth,charHeight must bigger than 0!");
		}
		int charIndex = 0;
		for (int y = 0; y < lines; y++) {
			for (int x = 0; x < xCount; x++) {
				TextureRegion region = new TextureRegion(tex, x * charWidth,
						tex.getRegionHeight() - (y + 1) * charHeight, charWidth,
						charHeight);
				dict.put(chars.charAt(charIndex), region);
				charIndex++;
			}
		}

		setTouchable(Touchable.disabled);
	}

	public RegionLabel(TextureRegion tex, String chars, int charWidth,
			int charHeight) {
		initialized(tex, chars, charWidth, charHeight);
	}

	public RegionLabel(TextureRegion tex, String chars) {
		this(tex, chars, 1);
	}

	public RegionLabel(TextureRegion tex, String chars, int lines) {
		int charWidth = tex.getRegionWidth() / (chars.length() / lines);
		int charHeight = tex.getRegionHeight() / lines;
		initialized(tex, chars, charWidth, charHeight);
	}

	private Group g;
	private int align = Align.topLeft;

	@Override
	public void setColor(Color color) {
		super.setColor(color);
		updateShow();
	}

	public void updateShow() {
		clearChildren();
		float offX = 0;
		float offY = 0;
		g = new Group();
		Group gc = new Group();
		for (int i = 0; i < text.length(); i++) {
			TextureRegion region = dict.get(text.charAt(i));
			if (region != null) {
				Image c = new Image(region);
				gc.addActor(c);
				c.setColor(getColor());
				c.setPosition(offX, offY);
				c.setOrigin(Align.left);
				offX += charWidth;
				if (!isAutoSize) {
					if (offX + charWidth > maxWidth) {
						offX = 0;
						offY -= charHeight;
					}
				}
			}
		}
		if (isAutoSize) {
			g.setWidth(offX);
			g.setHeight(charHeight);
		} else {
			if (offY < 0) {
				g.setWidth(maxWidth);
				g.setHeight(0 - offY + (offX == 0 ? 0 : charHeight));
			} else {
				g.setWidth(offX);
				g.setHeight(charHeight);
			}
		}
		g.addActor(gc);
		gc.setPosition(0, g.getHeight());

		addActor(g);
		g.setPosition(0, 0, align);

		setWidth(g.getWidth());
		setHeight(g.getHeight());

		if (offX > maxWidth) {
			setOrigin(Align.left);
			setScale(maxWidth / offX);
		}
	}

	public void setText(String text) {
		if (this.text.equals(text)) {
			return;
		}
		this.text = text;
		updateShow();
	}

	public void setText(Object obj) {
		String str = obj.toString();
		setText(str);
	}

	public String getText() {
		return text;
	}

	public void setCharWidth(int width) {
		charWidth = width;
		updateShow();
	}

	public int getCharWidth() {
		return charWidth;
	}

	public void setCharHeight(int height) {
		charHeight = height;
		updateShow();
	}

	public int getCharHeight() {
		return charHeight;
	}

	public int getMaxWidth() {
		return maxWidth;
	}

	public void setMaxWidth(int width) {
		maxWidth = width;
		updateShow();
	}

	public int getAlign() {
		return align;
	}

	public void setAlign(int align) {
		this.align = align;
		updateShow();
	}

	public boolean isAutoSize() {
		return isAutoSize;
	}

	public void setAutoSize(boolean isAutoSize) {
		this.isAutoSize = isAutoSize;
		updateShow();
	}

}
